﻿using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Media3D;
using System.Windows.Shapes;
using HalconDotNet;
using MachineVision.Core.Extensions;
using MachineVision.Core.TemplateMatch.Shared;
#nullable disable
namespace MachineVision.Shared.Controls
{
    public class ImageEditView : Control
    {
        public string PART_RECT = "PART_RECT";
        public string PART_CIRCLE = "PART_CIRCLE";
        public string PART_ELLIPSE = "PART_ELLIPSE";
        public string PART_REGON = "PART_REGON";
        public string PART_CLEAR = "PART_CLEAR";
        public string PART_MASK = "PART_MASK";
        public string PART_MSG = "PART_MSG";
        public string PART_HSmartWindow = "PART_HSmartWindow";

        private HSmartWindowControlWPF hSmartWindow;
        private HWindow hWindow;
        public TextBlock textMessage { get; private set; }

        public MatchResultSetting Setting
        {
            get { return (MatchResultSetting)GetValue(SettingProperty); }
            set { SetValue(SettingProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Setting.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SettingProperty = DependencyProperty.Register(
            "Setting",
            typeof(MatchResultSetting),
            typeof(ImageEditView),
            new PropertyMetadata(default, OnMatchSettingChanged)
        );

        private static void OnMatchSettingChanged(
            DependencyObject d,
            DependencyPropertyChangedEventArgs e
        ) { }

        public HObject MaskObject
        {
            get { return (HObject)GetValue(MaskObjectProperty); }
            set { SetValue(MaskObjectProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MaskObject.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MaskObjectProperty = DependencyProperty.Register(
            "MaskObject",
            typeof(HObject),
            typeof(ImageEditView),
            new PropertyMetadata(null)
        );

        public HObject Image
        {
            get { return (HObject)GetValue(ImageProperty); }
            set { SetValue(ImageProperty, value); }
        }

        public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
            "Image",
            typeof(HObject),
            typeof(ImageEditView),
            new PropertyMetadata(ImageValueChangeCallBack)
        );

        public ObservableCollection<DrawingObjectInfo> DrawingObjectInfos
        {
            get
            {
                return (ObservableCollection<DrawingObjectInfo>)
                    GetValue(DrawingObjectInfosProperty);
            }
            set { SetValue(DrawingObjectInfosProperty, value); }
        }

        public static readonly DependencyProperty DrawingObjectInfosProperty =
            DependencyProperty.Register(
                "DrawingObjectInfos",
                typeof(ObservableCollection<DrawingObjectInfo>),
                typeof(ImageEditView),
                new FrameworkPropertyMetadata(
                    new ObservableCollection<DrawingObjectInfo>(),
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault
                )
            );

        /// <summary>
        /// 依赖属性，便于其他服务控制该显示窗口
        /// </summary>
        public HWindow HWindow
        {
            get { return (HWindow)GetValue(HWindowProperty); }
            set { SetValue(HWindowProperty, value); }
        }
        public static readonly DependencyProperty HWindowProperty = DependencyProperty.Register(
            "HWindow",
            typeof(HWindow),
            typeof(ImageEditView),
            new FrameworkPropertyMetadata(
                null,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault
            )
        );

        //void DisplayMatchResult(ObservableCollection<TemplateMatchResult> results)
        //{
        //    if (results != null)
        //    {
        //        Display(Image);
        //        foreach (var item in results)
        //        {
        //            if (Setting != null)
        //            {
        //                if (Setting.IsShowCenter)
        //                    HOperatorSet.DispCross(hWindow, item.Row, item.Column, 50, item.Angle);
        //                if (Setting.IsShowDisplayText)
        //                    hWindow.SetString($"{item.Row} : {item.Column} : {Math.Round((180 / Math.PI) * item.Angle, 3)} : {item.Score}", "image", item.Row, item.Column, "black", "true");
        //                if (Setting.IsShowMatchRange)
        //                    HOperatorSet.DispObj(item.Contours, hWindow);
        //            }
        //        }
        //    }
        //}
        static void ImageValueChangeCallBack(
            DependencyObject d,
            DependencyPropertyChangedEventArgs e
        )
        {
            if (d is ImageEditView view && e.NewValue != null)
            {
                view.Display(e.NewValue as HObject);
                view.DrawingObjectInfos?.Clear();
            }
        }

        void Display(HObject obj)
        {
            try
            {
                hWindow.DispObj(obj);
                hWindow.SetPart(0, 0, -2, -2);
            }
            catch (Exception) { }
        }

        public override void OnApplyTemplate()
        {
            if (this.GetTemplateChild(PART_MSG) is TextBlock textblock)
                textMessage = textblock;
            if (this.GetTemplateChild(PART_CLEAR) is MenuItem bnclear)
                bnclear.Click += Bnclear_Click;
            if (this.GetTemplateChild(PART_ELLIPSE) is MenuItem bnellipse)
                bnellipse.Click += BnEllipseClick;
            if (this.GetTemplateChild(PART_RECT) is MenuItem bnrect)
                bnrect.Click += BnRectClick;
            if (this.GetTemplateChild(PART_REGON) is MenuItem bnregion)
                bnregion.Click += BnRegionClick;
            if ((this.GetTemplateChild(PART_CIRCLE)) is MenuItem bncircle)
                bncircle.Click += BnCircleClick;
            if ((this.GetTemplateChild(PART_MASK)) is MenuItem bnmask)
                bnmask.Click += BnMaskClick;
            if (this.GetTemplateChild(PART_HSmartWindow) is HSmartWindowControlWPF hSmart)
            {
                hSmartWindow = hSmart;
                hSmartWindow.Loaded += HSmartWindow_Loaded;
            }
            base.OnApplyTemplate();
        }

        private void Bnclear_Click(object sender, RoutedEventArgs e)
        {
            DrawingObjectInfos?.Clear();
            hWindow?.ClearWindow();
            if (Image != null)
                Display(Image);
        }

        private void HSmartWindow_Loaded(object sender, RoutedEventArgs e)
        {
            hWindow = hSmartWindow.HalconWindow;
            HWindow = hWindow;
        }

        private void BnMaskClick(object sender, RoutedEventArgs args)
        {
            DrawShape(ShapeType.Region);
        }

        void BnRectClick(object sender, RoutedEventArgs args)
        {
            DrawShape(ShapeType.Rectange, new HTuple(), new HTuple(), new HTuple(), new HTuple());
        }

        void BnCircleClick(object sender, RoutedEventArgs args)
        {
            DrawShape(ShapeType.Circle, new HTuple(), new HTuple(), new HTuple());
        }

        void BnEllipseClick(object sender, RoutedEventArgs args)
        {
            DrawShape(
                ShapeType.Ellipse,
                new HTuple(),
                new HTuple(),
                new HTuple(),
                new HTuple(),
                new HTuple()
            );
        }

        void BnRegionClick(object sender, RoutedEventArgs args)
        {
            DrawShape(ShapeType.Region);
        }

        async void DrawShape(ShapeType type, params HTuple[] hTuples)
        {
            HObject obj1 = null;
            HOperatorSet.GenEmptyObj(out obj1);
            HOperatorSet.SetColor(hWindow, "blue");
            textMessage.Text = "鼠标左键按下开始绘制,单击鼠标右键结束绘制";
            hSmartWindow.HZoomContent = HSmartWindowControlWPF.ZoomContent.Off; //开始绘制则禁用缩放功能，减少产生意外的可能
            switch (type)
            {
                case ShapeType.Rectange:

                    {
                        await Task.Run(() =>
                        {
                            HOperatorSet.DrawRectangle1(
                                hWindow,
                                out hTuples[0],
                                out hTuples[1],
                                out hTuples[2],
                                out hTuples[3]
                            );
                            HOperatorSet.GenRectangle1(
                                out obj1,
                                hTuples[0],
                                hTuples[1],
                                hTuples[2],
                                hTuples[3]
                            );
                        });
                    }
                    break;
                case ShapeType.Ellipse:

                    {
                        await Task.Run(() =>
                        {
                            HOperatorSet.DrawEllipse(
                                hWindow,
                                out hTuples[0],
                                out hTuples[1],
                                out hTuples[2],
                                out hTuples[3],
                                out hTuples[4]
                            );
                            HOperatorSet.GenEllipse(
                                out obj1,
                                hTuples[0],
                                hTuples[1],
                                hTuples[2],
                                hTuples[3],
                                hTuples[4]
                            );
                        });
                    }
                    break;
                case ShapeType.Circle:

                    {
                        await Task.Run(() =>
                        {
                            HOperatorSet.DrawCircle(
                                hWindow,
                                out hTuples[0],
                                out hTuples[1],
                                out hTuples[2]
                            );
                            HOperatorSet.GenCircle(out obj1, hTuples[0], hTuples[1], hTuples[2]);
                        });
                    }
                    break;
                case ShapeType.Region:

                    {
                        await Task.Run(() =>
                        {
                            HOperatorSet.DrawRegion(out obj1, hWindow);
                        });
                    }
                    break;
                default:
                    break;
            }
            if (type == ShapeType.Region)
            {
                MaskObject = obj1;
            }
            else if (obj1 != null)
            {
                DrawingObjectInfos?.Add(
                    new DrawingObjectInfo()
                    {
                        ShapeType = type,
                        HTuples = hTuples,
                        DrawObject = obj1
                    }
                );
                //生成指定区域的轮廓
                HObject region;
                HOperatorSet.GenContourRegionXld(obj1, out region, "border");
                HOperatorSet.DispObj(region, hWindow);
            }
            textMessage.Text = "";
            hSmartWindow.HZoomContent = HSmartWindowControlWPF.ZoomContent.WheelForwardZoomsIn;
        }
    }
}
